#include<string>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string_view>
#include<functional>
#include<iterator>
#include<any>
#include<map>
#include<chrono>
#include<fstream>
#include<sstream>
#include<memory>
#include<list>
#include<cctype>

#include "tinyxml.h"

using std::list;
using std::stringstream;
using std::ifstream;
using std::chrono::duration_cast;
using std::chrono::milliseconds;
using std::chrono::microseconds;
using std::chrono::high_resolution_clock;
using std::ostream_iterator;
using std::bind;
using std::logical_and;
using std::logical_or;
using std::not_equal_to;
using std::equal_to;
using std::copy;
using std::placeholders::_1;
using std::string_view;
using std::cout;
using std::string;
using std::vector;
using std::find;
using std::search;
using std::any;
using std::make_pair;
using std::pair;
using std::any_cast;
using std::getline;
using std::shared_ptr;
using std::unique_ptr;
using std::make_shared;
using std::ispunct;
using std::isdigit;
using std::make_unique;
using std::stable_sort;
using std::distance;


//  https://www.runoob.com/xml/xml-xsl.html   XML教程  支持除了命名空间情况外的简单XML
//  https://gitee.com/deng_dan_jun/function_finishing/tree/master/      MUP1.xml测试文件  太大的码云传不了
//  XML解析命名空间我认为没有必要做，因为很多XML文件中一个节点下面出现若干个命名空间的变量情况时有发生，采用排序算法编排过，在获取时加入前缀搜索也一样可以定位

struct Node
{
	Node() = default;

	Node(const char *p, const size_t n) :topName(p, n) {}

	Node(const char *p, const size_t n, const shared_ptr<Node> &otherFather) :topName(p, n), father(otherFather) {}

	Node(const char *p, const size_t n, const char *namespaceP, const size_t namespaceN, const shared_ptr<Node> &otherFather) :topName(p, n), father(otherFather)
	{
		if (father->childNamespace.empty())
		{
			father->childNamespace.emplace_back(make_unique<pair<string_view, int>>(make_pair(string_view(namespaceP, namespaceN), -1)));
			return;
		}
		else
		{
			if (find_if(father->childNamespace.cbegin(), father->childNamespace.cend(), [&namespaceP, &namespaceN](auto const &myPair)
			{
				return distance(myPair->first.begin(), myPair->first.end()) == namespaceN && equal(myPair->first.begin(), myPair->first.end(), namespaceP, namespaceP + namespaceN);
			}) == father->childNamespace.cend())
				father->childNamespace.emplace_back(make_unique<pair<string_view, int>>(make_pair(string_view(namespaceP, namespaceN), -1)));
		}
	}

	//凡是需要排序的地方都用智能指针封装，这样排序变换时提高速度
	string_view topName;
	vector<unique_ptr<pair<string_view, string_view>>>value;
	string_view text;
	vector<unique_ptr<pair<string_view, int>>>childNamespace;    //子节点层名如果有命名空间，则存储在这里，  key 命名空间名称  value   child里面对应的和begin之间的距离用于快速查找特定命名空间的变量
	vector<shared_ptr<Node>>child;                              //子节点
	shared_ptr<Node>father;
};




struct STLXML
{
	shared_ptr<Node>ptr;       //真正存储XML节点DOM树的起点
	shared_ptr<Node>head;      //head类似指针遍历的head，遍历操作挑战用

	size_t sourceBegin, sourceEnd;
	size_t topBegin, topEnd, valueBegin, valueEnd, wordBegin, wordEnd, namespaceBegin, namespaceEnd,stempBegin,stempEnd;    //   value为层级下的值名   word为值对应的“”内容
	size_t topNameBegin, topNameEnd;  //topname保存层名
	size_t iterFind;
	vector<pair<string_view, string_view>>xml;   //保存一开始xml层的值
	vector<vector<shared_ptr<Node>>::const_iterator>sortVec;    //用于排序
	int sortNum{ -1 };     //排序层数
	bool success{ false };    //是否解析成功
};



void preaseXML(STLXML &s1, const string_view &source)
{
	if (source.empty())
		return;
	static string xml{ "xml" };
	static const char *left{ "<" }, *space{ " " }, *findStr1{ "->" }, *findStr2{ " >" }, *findStr3{ "=>" }, *findstr4{ "\">" }, *findStr5{ ":" }, *noteBegin{ "!--" }, *noteEnd{ "-->" }, *CDATABegin{ "<![CDATA[" }, *CDATAEnd{ "]]>" }, *findStr6{" \t"};
	static const int CDATABeginLen{ (CDATABegin?distance(CDATABegin,find(CDATABegin,CDATABegin + INT_MAX,0)):0) }, CDATAEndLen{ (CDATAEnd?distance(CDATAEnd,find(CDATAEnd,CDATAEnd + INT_MAX,0)):0) }, noteBeginLen{ (noteBegin?distance(noteBegin,find(noteBegin,noteBegin + INT_MAX,0)):0) }, noteEndLen{ (noteEnd?distance(noteEnd,find(noteEnd,noteEnd + INT_MAX,0)):0) };


	s1.sourceBegin = 0;
	s1.sourceEnd = source.size();
	s1.ptr.reset();
	s1.head.reset();
	s1.xml.clear();
	s1.topBegin = s1.sourceBegin;
	s1.success = true;

	while (s1.topBegin != string_view::npos)
	{
		if ((s1.topBegin = source.find(left, s1.topBegin, 1)) == string_view::npos)
		{
			s1.success = false;
			break;
		}

		if ((s1.topNameBegin = source.find_first_not_of(space, s1.topBegin + 1, 1)) == string_view::npos)
		{
			s1.success = false;
			break;
		}

		if (*(source.begin() + s1.topNameBegin) == '/')           //XML标签结束
		{
			if (!s1.head  && s1.head != s1.ptr && !s1.head->father)
			{
				s1.success = false;
				break;
			}

			if (s1.sourceEnd - (s1.topNameBegin + 1) < (s1.head->topName.size() + 1) || !(source.compare(s1.topNameBegin + 1, s1.topNameBegin + 1 + s1.head->topName.size(), s1.head->topName, 0, s1.head->topName.size()) == 1 && *(source.begin() + s1.topNameBegin + 1 + s1.head->topName.size()) == '>'))
			{
				s1.success = false;
				break;
			}

			s1.topBegin = source.find(left, s1.topNameBegin + s1.head->topName.size() + 1, 1);
			if (s1.head->father)
				s1.head = s1.head->father;
			continue;
		}

		if (*(source.begin() + s1.topNameBegin) == '!')    // XML注释
		{
			if (s1.sourceEnd - s1.topNameBegin < noteBeginLen || source.compare(s1.topNameBegin, s1.topNameBegin + noteBeginLen, noteBegin, 0, noteBeginLen) != 1)
			{
				s1.success = false;
				break;
			}
			if ((s1.iterFind = source.find(noteEnd, s1.topNameBegin + noteBeginLen, noteEndLen)) == string_view::npos)
			{
				s1.success = false;
					break;
			}
			s1.topBegin = source.find(left,s1.iterFind + noteEndLen,1);
			continue;
		}


		if (*(source.begin() + s1.topNameBegin) == '?')          //可能是XML首层的情况   <?xml version="1.0" encoding="UTF-8"?>
		{

			if ((s1.topNameEnd = source.find_first_of(findStr2, s1.topNameBegin + 1, 2)) == string_view::npos)
			{
				s1.success = false;
				break;
			}
			if (source.compare(s1.topNameBegin + 1, s1.topNameEnd, xml, 0, xml.size()) != 1)
			{
				s1.success = false;
				break;
			}

			s1.valueBegin = s1.topNameEnd;

			while ((s1.valueBegin = source.find_last_not_of(space, s1.valueBegin, 1)) != string::npos && *(source.begin() + s1.valueBegin) != '?')
			{
				if ((s1.valueEnd = source.find_first_of(findStr3, s1.valueBegin, 2)) == string_view::npos || *(source.begin() + s1.valueEnd) == '>')
				{
					s1.valueBegin = s1.valueEnd;
					break;
				}

				if ((s1.wordBegin = source.find_first_of(findstr4, s1.valueEnd + 1, 2)) == string_view::npos || *(source.begin() + s1.wordBegin) == '>')
				{
					s1.valueBegin = s1.wordBegin;
					break;
				}

				if ((s1.wordEnd = source.find_first_of(findstr4, s1.wordBegin + 1, 2)) == string_view::npos || *(source.begin() + s1.wordEnd) == '>')
				{
					s1.valueBegin = s1.wordBegin;
					break;
				}

				if (s1.valueEnd - s1.valueBegin && s1.wordEnd - s1.wordBegin)
				{
					s1.xml.emplace_back(make_pair(string_view(&source[0] + (s1.valueBegin - s1.sourceBegin), s1.valueEnd - s1.valueBegin), string_view(&source[0] + s1.wordBegin - s1.sourceBegin + 1, s1.wordEnd - s1.wordBegin - 1)));
				}

				s1.valueBegin = s1.wordEnd + 1;
			}
		}

		if (*(source.begin() + s1.topNameBegin) == '?' && *(source.begin() + s1.valueBegin) == '?')   //  <?xml version="1.0" encoding="UTF-8"?>
		{
			s1.topBegin = source.find(left, s1.valueBegin, 1);
			continue;
		}

		if (*(source.begin() + s1.topNameBegin) > 0 && (*(source.begin() + s1.topNameBegin) == '<' || *(source.begin() + s1.topNameBegin) == '>' || ispunct(*(source.begin() + s1.topNameBegin)) || isdigit(*(source.begin() + s1.topNameBegin))))   //  名称不能以数字或者标点符号开始
		{
			s1.success = false;
			break;
		}

		if ((s1.topNameEnd = source.find_first_of(findStr2, s1.topNameBegin + 1, 2)) == string_view::npos)
		{
			s1.success = false;
			break;
		}

		if (*(source.begin() + s1.topNameEnd) == '>')   //    名称不能包含空格    名称不能以字母 xml（或者 XML、Xml 等等）开始
		{
			string_view stemp1{ &source[0] + s1.topNameBegin ,s1.topNameEnd - s1.topNameBegin };
			if (!(s1.topNameEnd - s1.topNameBegin) || stemp1.find(" ", 0, 1)!=string_view::npos || (s1.topNameEnd - s1.topNameBegin > 2 && (*(source.begin() + s1.topNameBegin) == 'X' || *(source.begin() + s1.topNameBegin) == 'x') && (*(source.begin() + s1.topNameBegin + 1) == 'M' || *(source.begin() + s1.topNameBegin + 1) == 'm') && (*(source.begin() + s1.topNameBegin + 2) == 'L' || *(source.begin() + s1.topNameBegin + 2) == 'l')))
			{
				s1.success = false;
				break;
			}

			if (!s1.ptr)
			{
				s1.ptr = make_shared<Node>(&source[0] + s1.topNameBegin - s1.sourceBegin, s1.topNameEnd - s1.topNameBegin);
				s1.head = s1.ptr;
			}
			else   //  判断是否有除了默认命名空间外的层名，比如    SOAP-ENV:Body   如果命名空间不在其插入节点的父节点namespace 容器中则进行插入命名空间操作
			{
				string_view stemp{ &source[0] + s1.topNameBegin ,s1.topNameEnd - s1.topNameBegin };
				if ((s1.stempBegin = stemp.find(findStr5, 0,1)) != string_view::npos)
				{
					auto temp{ make_shared<Node>(&source[0] + s1.topNameBegin - s1.sourceBegin, s1.topNameEnd - s1.topNameBegin, &source[0] + s1.topNameBegin - s1.sourceBegin, s1.stempBegin,   s1.head) };
					s1.head->child.emplace_back(temp);
					s1.head = temp;
				}
				else
				{
					auto temp{ make_shared<Node>(&source[0] + s1.topNameBegin - s1.sourceBegin, s1.topNameEnd -s1.topNameBegin,s1.head) };
					s1.head->child.emplace_back(temp);
					s1.head = temp;
				}
			}


			s1.topBegin = source.find(left, s1.topNameEnd + 1, 1);

			string_view stemp{ &source[0] + s1.topNameEnd + 1 ,s1.topBegin - s1.topNameEnd - 1 };
			if ((s1.topBegin - s1.topNameEnd) < 2 || stemp.find_first_not_of(findStr6,0,2)==string_view::npos)
				continue;

			s1.head->text.swap(string_view(&source[0] + s1.topNameEnd + 1 - s1.sourceBegin, s1.topBegin - s1.topNameEnd - 1));

			continue;
		}

		string_view stemp{ &source[0] + s1.topNameBegin ,s1.topNameEnd- s1.topNameBegin };
		if (!(s1.topNameEnd - s1.topNameBegin) || stemp.find(space, 0, 1) != string_view::npos || ((s1.topNameEnd - s1.topNameBegin) > 2 && (*(source.begin() + s1.topNameBegin) == 'X' || *(source.begin() + s1.topNameBegin) == 'x') && (*(source.begin() + s1.topNameBegin + 1) == 'M' || *(source.begin() + s1.topNameBegin + 1) == 'm') && (*(source.begin() + s1.topNameBegin + 2) == 'L' || *(source.begin() + s1.topNameBegin + 2) == 'l')))
		{
			s1.success = false;
			break;
		}

		if (!s1.ptr)
		{
			s1.ptr = make_shared<Node>(&source[0] + s1.topNameBegin - s1.sourceBegin, s1.topNameEnd - s1.topNameBegin);
			s1.head = s1.ptr;
		}
		else   //  判断是否有除了默认命名空间外的层名，比如    SOAP-ENV:Body   如果命名空间不在其插入节点的父节点namespace 容器中则进行插入命名空间操作
		{
			string_view stemp{ &source[0] + s1.topNameBegin ,s1.topNameEnd - s1.topNameBegin };
			if ((s1.stempBegin = stemp.find(findStr5, 0, 1)) != string_view::npos)
			{
				auto temp{ make_shared<Node>(&source[0] + s1.topNameBegin - s1.sourceBegin, s1.topNameEnd - s1.topNameBegin, &source[0] + s1.topNameBegin - s1.sourceBegin, s1.stempBegin,   s1.head) };
				s1.head->child.emplace_back(temp);
				s1.head = temp;
			}
			else
			{
				auto temp{ make_shared<Node>(&source[0] + s1.topNameBegin - s1.sourceBegin, s1.topNameEnd - s1.topNameBegin,s1.head) };
				s1.head->child.emplace_back(temp);
				s1.head = temp;
			}
		} 

		s1.valueBegin = s1.topNameEnd;

		//循环存储里面的值    比如 <book category="CHILDREN"> 的category="CHILDREN"
		while ((s1.valueBegin = source.find_first_not_of(space, s1.valueBegin, 1)) != string_view::npos && *(source.begin() + s1.valueBegin) != '>' && *(source.begin() + s1.valueBegin) != '/')
		{

			if ((s1.valueEnd = source.find_first_of(findStr3, s1.valueBegin, 2)) == string_view::npos || *(source.begin() + s1.valueEnd) == '>')
			{
				s1.valueBegin = s1.valueEnd;
				break;
			}

			if ((s1.wordBegin = source.find_first_of(findstr4, s1.valueEnd, 2)) == string_view::npos || *(source.begin() + s1.wordBegin) == '>')
			{
				s1.valueBegin = s1.wordBegin;
				break;
			}

			if ((s1.wordEnd = source.find_first_of(findstr4, s1.wordBegin + 1, 2)) == string_view::npos || *(source.begin() + s1.wordEnd) == '>')
			{
				s1.valueBegin = s1.wordBegin;
				break;
			}

			if (s1.valueEnd - s1.valueBegin && s1.wordEnd - s1.wordBegin)
			{
				if (!s1.head)
				{
					s1.success = false;
					break;
				}
				s1.head->value.emplace_back(make_unique<pair<string_view, string_view>>(make_pair(string_view(&source[0] + s1.valueBegin - s1.sourceBegin, s1.valueEnd - s1.valueBegin), string_view(&source[0] + s1.wordBegin - s1.sourceBegin + 1, s1.wordEnd - s1.wordBegin - 1))));
			}

			s1.valueBegin = s1.wordEnd + 1;
		}

		if (!(s1.sourceEnd - s1.valueBegin))
		{
			s1.success = false;
			break;
		}

		if ((s1.sourceEnd - s1.valueBegin) > 1 && *(source.begin() + s1.valueBegin) == '/' && *(source.begin() + s1.valueBegin + 1) == '>')    //   XML空标签
		{
			if (!s1.head || !s1.head->father)
			{
				s1.success = false;
				break;
			}
			s1.head = s1.head->father;
			s1.topBegin = source.find(left, s1.valueBegin + 2, 1);
			continue;
		}

		s1.topBegin = source.find(left, s1.valueBegin + 1, 1);   //判断两个标签> <之间是否有文本需要保存  比如 <title>Harry Potter</title>中的Harry Potter


		string_view stemp1{ &source[0] + s1.valueBegin + 1 ,s1.topBegin - s1.valueBegin - 1 };
		if ((s1.topBegin - s1.valueBegin) < 2 || stemp1.find_first_not_of(findStr6,0,2)==string_view::npos )   //  CDATA
		{

			if ((s1.sourceEnd - s1.topBegin) > CDATABeginLen && source.compare(s1.valueBegin + 1, s1.valueBegin + 1 + CDATABeginLen, CDATABegin, 0, CDATABeginLen) == 1)
			{

				if ((s1.topBegin = source.find(CDATAEnd, s1.topBegin + CDATABeginLen, CDATAEndLen)) == string_view::npos)
				{
					s1.success = false;
					break;
				}

				s1.topBegin += CDATAEndLen;

				if (!s1.head)
				{
					s1.success = false;
					break;
				}
				s1.head->text.swap(string_view(&source[0] + s1.valueBegin + 1 - s1.sourceBegin, s1.topBegin - s1.valueBegin - 1));
			}
			continue;
		}

		if (!s1.head)
		{
			s1.success = false;
			break;
		}

		s1.head->text.swap(string_view(&source[0] + s1.valueBegin + 1 - s1.sourceBegin, s1.topBegin - s1.valueBegin - 1));
	}
	if (s1.success && s1.ptr && s1.head == s1.ptr)  //确认解析成功才去进行排序，提高处理速度   可能有bug  我很艰难才写出这个  ，默认规则是先跳到最左边一层的没有子节点的子点，然后从最底层节点开始向上迭代，将全部节点排序
	{
		s1.head = s1.ptr;
		s1.sortVec.clear();
		s1.sortNum = -1;
		if (!s1.head->child.empty())
		{
			++s1.sortNum;
			string_view::const_iterator leftIter, rightIter;
			vector<unique_ptr<pair<string_view, int>>>::iterator iterNamespace;
			vector<shared_ptr<Node>>::const_iterator iterChild;
			while (!(s1.head == s1.ptr && !s1.sortVec.empty() && s1.sortVec[0] == s1.head->child.cend()))
			{
				if (!s1.head->child.empty())
				{
					if (s1.sortVec.size() < s1.sortNum + 1)
					{
						++s1.sortNum;
						s1.sortVec.emplace_back(s1.head->child.cbegin());
						s1.head = *s1.sortVec.back();
						continue;
					}
					if (s1.sortVec[s1.sortNum] == s1.head->child.cend())
					{
						if (!s1.head->value.empty())
						{
							stable_sort(s1.head->value.begin(), s1.head->value.end(), [](auto const &left, auto const &right)
							{
								return left->first < right->first;
							});
						}

						// 如果有非默认命名空间存在则进行考虑存在命名空间的排序操作

						if (s1.head->childNamespace.empty())  //没有非默认命名空间的情况下只进行根据子节点topnam排序即可e
						{
							stable_sort(s1.head->child.begin(), s1.head->child.end(), [](auto const &left, auto const &right)
							{
								return left->topName < right->topName;
							});
						}
						else
						{
							//  有非默认命名空间，则进行以下操作来排序
							//  1  首先对命名空间名称本身进行排序
							//  2  根据child的层名进行排序，规则如下（较复杂）：
							//   不同命名空间的情况下，默认命名空间优先级最高，其次就是命名空间间进行排序比对
							//   同样的命名空间变量里面，以命名空间后面的字符串进行比对排序
							//   以上结束后，遍历child 容器，将首次出现对应命名空间的位置赋值给命名空间容器记录的位置中，方便后面查找时使用

							sort(s1.head->childNamespace.begin(), s1.head->childNamespace.end(), [](auto const &left, auto const &right)
							{
								return left->first < right->first;
							});
							stable_sort(s1.head->child.begin(), s1.head->child.end(), [&leftIter, &rightIter](auto const &left, auto const &right)
							{
								leftIter = find(left->topName.cbegin(), left->topName.cend(), ':');
								rightIter = find(right->topName.cbegin(), right->topName.cend(), ':');
								if (leftIter == left->topName.cend())
								{
									if (rightIter == right->topName.cend())
										return left->topName < right->topName;
									return true;
								}
								else
								{
									if (rightIter == right->topName.cend())
										return false;
									if (distance(left->topName.cbegin(), leftIter) == distance(right->topName.cbegin(), rightIter))
									{
										if (equal(left->topName.cbegin(), leftIter, right->topName.cbegin(), rightIter))
											return lexicographical_compare(leftIter + 1, left->topName.cend(), rightIter + 1, right->topName.cend());
										return lexicographical_compare(left->topName.cbegin(), leftIter, right->topName.cbegin(), rightIter);
									}
									return lexicographical_compare(left->topName.cbegin(), leftIter, right->topName.cbegin(), rightIter);
								}
							});
							iterNamespace = s1.head->childNamespace.begin();
							iterChild = s1.head->child.begin();
							while (iterNamespace != s1.head->childNamespace.end())
							{
								while (iterChild != s1.head->child.end())
								{
									if ((leftIter = find((*iterChild)->topName.begin(), (*iterChild)->topName.end(), ':')) != (*iterChild)->topName.end())
									{
										if (distance((*iterChild)->topName.begin(), leftIter) == (*iterNamespace)->first.size() && equal((*iterChild)->topName.begin(), leftIter, (*iterNamespace)->first.begin(), (*iterNamespace)->first.end()))
										{
											(*iterNamespace)->second = distance(s1.head->child.cbegin(), iterChild);
											++iterNamespace;
											++iterChild;
											break;
										}
									}
									++iterChild;
								}
							}
							//							cout << "yes\n";
						}
						s1.head = s1.head->father;
						--s1.sortNum;
						++s1.sortVec[s1.sortNum];
						continue;
					}
					s1.head = *(s1.sortVec[s1.sortNum]);
					++s1.sortNum;
					if (!s1.head->child.empty())
					{
						if (s1.sortVec.size() < s1.sortNum + 1)
							s1.sortVec.emplace_back(s1.head->child.cbegin());
						else
							s1.sortVec[s1.sortNum] = s1.head->child.cbegin();
					}
					continue;
				}
				if (!s1.head->value.empty())
				{
					stable_sort(s1.head->value.begin(), s1.head->value.end(), [](auto const &left, auto const &right)
					{
						return left->first < right->first;
					});
				}
				s1.head = s1.head->father;
				--s1.sortNum;
				++s1.sortVec[s1.sortNum];
			}
			if (!s1.head->value.empty())
			{
				stable_sort(s1.head->value.begin(), s1.head->value.end(), [](auto const &left, auto const &right)
				{
					return left->first < right->first;
				});
			}
			if (s1.head->childNamespace.empty())
			{
				stable_sort(s1.head->child.begin(), s1.head->child.end(), [](auto const &left, auto const &right)
				{
					return left->topName < right->topName;
				});
			}
			else
			{
				sort(s1.head->childNamespace.begin(), s1.head->childNamespace.end(), [](auto const &left, auto const &right)
				{
					return left->first < right->first;
				});
				stable_sort(s1.head->child.begin(), s1.head->child.end(), [&leftIter, &rightIter](auto const &left, auto const &right)
				{
					leftIter = find(left->topName.cbegin(), left->topName.cend(), ':');
					rightIter = find(right->topName.cbegin(), right->topName.cend(), ':');
					if (leftIter == left->topName.cend())
					{
						if (rightIter == right->topName.cend())
							return left->topName < right->topName;
						return true;
					}
					else
					{
						if (rightIter == right->topName.cend())
							return false;
						if (distance(left->topName.cbegin(), leftIter) == distance(right->topName.cbegin(), rightIter))
						{
							if (equal(left->topName.cbegin(), leftIter, right->topName.cbegin(), rightIter))
								return lexicographical_compare(leftIter + 1, left->topName.cend(), rightIter + 1, right->topName.cend());
							return lexicographical_compare(left->topName.cbegin(), leftIter, right->topName.cbegin(), rightIter);
						}
						return lexicographical_compare(left->topName.cbegin(), leftIter, right->topName.cbegin(), rightIter);
					}
				});
				iterNamespace = s1.head->childNamespace.begin();
				iterChild = s1.head->child.begin();
				while (iterNamespace != s1.head->childNamespace.end())
				{
					while (iterChild != s1.head->child.end())
					{
						if ((leftIter = find((*iterChild)->topName.begin(), (*iterChild)->topName.end(), ':')) != (*iterChild)->topName.end())
						{
							if (distance((*iterChild)->topName.begin(), leftIter) == (*iterNamespace)->first.size() && equal((*iterChild)->topName.begin(), leftIter, (*iterNamespace)->first.begin(), (*iterNamespace)->first.end()))
							{
								(*iterNamespace)->second = distance(s1.head->child.cbegin(), iterChild);
								++iterNamespace;
								++iterChild;
								break;
							}
						}
						++iterChild;
					}
				}
				//				cout << "yes\n";
			}
		}
		else
		{
			stable_sort(s1.head->value.begin(), s1.head->value.end(), [](auto const &left, auto const &right)
			{
				return left->first < right->first;
			});
		}
	}
	else
		s1.success = false;
}







int main()
{
	vector<string>vec{
	"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
<note>\
  <to>Tove</to>\
  <from>Jani</from>\
  <heading>Reminder</heading>\
  <body>Don't forget me this weekend!</body>\
</note>",

		"<bookstore>\
	<book category=\"COOKING\">\
		<title lang=\"en\">Everyday Italian</title>\
		<author>Giada De Laurentiis</author>\
		<year>2005</year>\
		<price>30.00</price>\
	</book>\
	<book category=\"CHILDREN\">\
		<title lang=\"en\">Harry Potter</title>\
		<author>J K.Rowling</author>\
		<year>2005 </year>\
		<price>29.99</price>\
	</book>\
	<book category=\"WEB\">\
		<btest lang=\"en\">Learning XML</title>\
		<author>Erik T.Ray</author>\
		<year>2003</year>\
		<price>39.95</price>\
	</book>\
</bookstore>"
	};

	char *p{ "<bookstore>\
<!-- This is a comment -->\
	<book3 category=\"COOKING\">\
		<title lang=\"en\"><![CDATA[\
function matchwo(a,b)\
{\
if (a < b && a < 0) then\
{\
return 1;\
}\
else\
{\
return 0;\
}\
}\
]]></title>\
		<author>Giada De Laurentiis</author>\
		<year>2005</year>\
		<price>30.00</price>\
	</book3>\
	<book2 category=\"CHILDREN\">\
	</book2>\
	<book1 category=\"WEB\">\
		<btest lang=\"en\">Learning XML</btest>\
		<author>Erik T.Ray</author>\
		<year>2003</year>\
		<price>39.95</price>\
	</book1>\
</bookstore>" };
	string test{ p };




	int i{};



	ifstream file("G:/09IME/MUP1.xml", std::ios::binary);
	if (file)
	{
		string fileStr;
		stringstream sstr;
		while (!file.eof())
		{
			getline(file, fileStr);
			if (!fileStr.empty() && fileStr.back() == '\r')
				fileStr.erase(fileStr.end() - 1);
			if (!fileStr.empty())
				sstr << fileStr;
		}
		fileStr.assign(sstr.str());

		shared_ptr<TiXmlDocument>myDocument{ new TiXmlDocument() };
		auto t1{ high_resolution_clock::now() };
		myDocument->Parse(fileStr.c_str());
		myDocument->Clear();
		cout << duration_cast<milliseconds>(high_resolution_clock::now() - t1).count() << " ms  \n";

		i = 0;
		STLXML s1;
		auto t2{ high_resolution_clock::now() };
		preaseXML(s1, fileStr);
		cout << duration_cast<milliseconds>(high_resolution_clock::now() - t2).count() << " ms  \n";
	}


	return 0;
}
